<?php

namespace common\logics\workflow;

use Yii;
use yii\helpers\Inflector;
use common\models\shop\ShopOrderRefund;
use common\models\shop\ShopOrderRefundLog;
use common\models\shop\ShopOrderRefundWorkflow;

/**
 * 流程自动执行逻辑器
 *
 * @author emhome <emhome@163.com>
 * @since 2.0
 */
class RefundWorkflowLogic extends \common\base\Model {

    /**
     * @var ShopOrderRefund
     */
    public $refund;

    /**
     * @var ShopOrderRefundWorkflow 
     */
    public $workflow;

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            ['refund', 'required'],
            ['workflow', 'required'],
        ];
    }

    /**
     * @inheritdoc
     */
    public static function recordLog($data) {
        Yii::error($data, 'workflow');
    }

    /**
     * @inheritdoc
     */
    public function execute() {
        static::recordLog([
            'MESSAGE' => '运行自动工作流',
            'REFUND' => $this->refund->attributes,
            'WORKFLOW' => $this->workflow->attributes,
        ]);
        if (!$this->validate()) {
            static::recordLog([
                'MESSAGE' => '运行自动工作流-校验失败',
                'ERROR' => $this->getErrorMsg()
            ]);
            return false;
        }
        $refund = $this->refund;
        $workflow = $this->workflow;

        //无后续流程，执行终止流程
        if (!($workflow->next_id && $workflow->fallback_id)) {
            static::recordLog([
                'MESSAGE' => '无后续流程，执行终止流程',
                'WORKFLOW' => $workflow->attributes,
            ]);
            return $workflow->finish($refund);
        }

        //单一流程
        if ($workflow->next_id == $workflow->fallback_id) {
            static::recordLog([
                'MESSAGE' => '单一流程',
            ], 'workflow');
            if (!$workflow->role_id) {
                //执行单一流程
                static::recordLog([
                    'MESSAGE' => '执行单一流程',
                ]);
                if ($workflow->index == $workflow->next_id) {
                    //暂停流程
                    static::recordLog([
                        'MESSAGE' => '暂停流程',
                        'action' => 'wait',
                    ], 'workflow');
                    return $workflow->wait($refund);
                }
                //自动下一流程
                static::recordLog([
                    'MESSAGE' => '自动下一流程',
                    'action' => 'next',
                ]);
                //自动下一流程
                if ($workflow->duration > 0 && $workflow->next_id == $workflow->expire_id) {
                    static::recordLog([
                        'MESSAGE' => '自动操控流程 等待队列延迟' . $workflow->duration . 's执行',
                    ]);
                    $workflow->pushExpireJob($refund);
                    return $refund;
                }
                //自动下一流程 - 立即执行
                return $workflow->next($refund);
            } else {
                //人为审核操控流程
                //等待人工操作
                static::recordLog([
                    'MESSAGE' => '人为审核操控流程 等待人工操作',
                ]);
            }
        }


        //特殊操作，银行退款
        $refundState = null;
        if ($workflow->role_id === ShopOrderRefundWorkflow::ROLE_BANK) {
            $refundState = $workflow->bankRefund($refund, $workflow);
            if ($refundState === true) {
                //自动下一流程 - 立即执行
                return $workflow->next($refund);
            }
        }
        //超时流程
        if ($workflow->duration && $workflow->expire_id) {
            $retry = true;
            //执行超时自动任务流
            static::recordLog([
                'MESSAGE' => '运行自动工作流-创建过期时自动流程任务',
                'flowid' => $workflow->id,
                'max_retry' => $workflow->max_retry,
            ]);
            if ($workflow->max_retry) {
                $retries = ShopOrderRefundLog::findRetryTimes($refund->id, $workflow->id);
                if ($retries > $workflow->max_retry) {
                    $retry = false;
                }
                //执行超时自动任务流
                static::recordLog([
                    'MESSAGE' => '运行自动工作流-创建过期时自动流程任务',
                    'flowid' => $workflow->id,
                    'retries' => $retries,
                    'max_retry' => $workflow->max_retry,
                ]);
            }
            if ($retry) {
                //执行超时自动任务流
                static::recordLog([
                    'MESSAGE' => '运行自动工作流-创建过期时自动流程任务',
                ]);
                $workflow->pushExpireJob($refund);
            }
        }
        return $refund;
    }

}
